import { resolve } from "path";
import fs from "node:fs";
import unzipper from "unzipper";

export class FileUtils {
  /**
   * 读取指定路径处的文件内容。
   *
   * @param {string} path - 要读取的文件的路径。
   * @return {string} 文件的内容。
   */
  static readFile(path: string) {
    return fs.readFileSync(path, "utf8");
  }

  /**
   * 将一组路径段解析为单个路径。
   *
   * @param {string[]} path - 路径段数组。
   * @return {string} 解析的单个路径。
   */
  static resolvePath(path: string[]) {
    return resolve(...path);
  }

  /**
   * 将提供的数据保存到指定路径的文件中。
   *
   * @param {string} path - 将保存数据的文件路径。
   * @param {ArrayBuffer} data - 要写入文件的数据。
   * @return {void} 不返回值。
   */
  static saveFile(path: string, data: Buffer | string) {
    fs.writeFileSync(path, data);
  }

  /**
   * 检查指定的路径是否存在。
   *
   * @param {string} path - 检查是否存在的路径。
   * @return {boolean} - 如果路径存在，则返回 true，否则返回 false。
   */
  static exist(path: string) {
    return fs.existsSync(path);
  }

  /**
   * 获取文件属性
   * @param path
   */
  static attributes(path: string): { birthtime?: string; size?: number } {
    if (FileUtils.exist(path)) {
      return fs.statSync(path) as any;
    }
    return {};
  }

  /**
   * 解压缩
   * @param path
   * @param destPath
   */
  static unpack(path: string, destPath: string) {
    if (!FileUtils.exist(destPath)) {
      fs.mkdirSync(destPath, { recursive: true });
    }
    return new Promise<void>((resolve, reject) => {
      fs.createReadStream(path)
        .pipe(unzipper.Extract({ path: destPath }))
        .on("close", () => {
          resolve();
        })
        .on("error", (err) => {
          reject(err);
        });
    });
  }

  static readJSON<T, R = T>(path: string, converter?: (json: T) => R) {
    const rows = JSON.parse(FileUtils.readFile(path)) as T[];
    if (!converter) {
      return rows as never as R[];
    }
    return rows.map((row) => converter(row));
  }
  static writeJSON<T>(path: string, json: T) {
    FileUtils.saveFile(path, JSON.stringify(json));
  }
}
